package com.huanxing.cloud.mall.api.handler.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huanxing.cloud.common.core.constant.CacheConstants;
import com.huanxing.cloud.common.core.constant.SecurityConstants;
import com.huanxing.cloud.common.core.entity.Result;
import com.huanxing.cloud.mall.api.service.IDistributionUserService;
import com.huanxing.cloud.mall.api.service.IUserInfoService;
import com.huanxing.cloud.mall.api.utils.HxTokenHolder;
import com.huanxing.cloud.mall.common.constant.MallUserConstants;
import com.huanxing.cloud.mall.common.dto.HxTokenInfo;
import com.huanxing.cloud.mall.common.dto.UserLoginDTO;
import com.huanxing.cloud.mall.common.entity.UserInfo;
import com.huanxing.cloud.mall.common.feign.FeignAliUserService;
import com.huanxing.cloud.miniapp.common.dto.AliUserDTO;
import com.huanxing.cloud.miniapp.common.entity.AliUser;
import com.huanxing.cloud.security.handler.HxBusinessException;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@Component("ALI_MA_PHONE_LOGIN")
@AllArgsConstructor
public class AliPayPhoneLoginHandler extends AbstractLoginHandler {

	private IUserInfoService userInfoService;

	private final FeignAliUserService feignAliUserService;

	private final RedisTemplate<String, String> redisTemplate;

	private final IDistributionUserService distributionUserService;

	@Override
	public void before(UserLoginDTO userLoginDTO) {
	}

	@Override
	public UserInfo doLogin(UserLoginDTO userLoginDTO) {
		HxTokenInfo hxTokenInfo = HxTokenHolder.getTokenInfo();
		String key = CacheConstants.MALL_USER_TOKEN + userLoginDTO.getHxToken();

		AliUserDTO aliUserDTO = new AliUserDTO();
		aliUserDTO.setAppId(userLoginDTO.getAppId());
		aliUserDTO.setClientType(userLoginDTO.getClientType());
		aliUserDTO.setEncryptedData(userLoginDTO.getEncryptedData());
		Result result = feignAliUserService.getPhoneNumberInfo(aliUserDTO, SecurityConstants.SOURCE_IN);
		String phone = result.getData().toString();
		UserInfo userInfo = userInfoService
			.getOne(Wrappers.<UserInfo>lambdaQuery().eq(UserInfo::getPhone, userLoginDTO.getPhone()));
		if (ObjectUtil.isNull(userInfo)) {
			userInfo = new UserInfo();
			userInfo.setUserGrade(MallUserConstants.USER_GRADE_0);
			userInfo.setAvatarUrl(MallUserConstants.DEFAULT_AVATAR_URL);
			userInfo.setUserSource(userLoginDTO.getClientType());
			userInfo.setAccountBalance(BigDecimal.ZERO);
		}
		Result<AliUser> aliUserResult = feignAliUserService.getById(hxTokenInfo.getAliUserId(),
				SecurityConstants.SOURCE_IN);
		if (Boolean.FALSE.equals(aliUserResult.isOk())) {
			throw new HxBusinessException(aliUserResult.getMsg());
		}
		AliUser aliUser = aliUserResult.getData();

		if (StrUtil.isBlank(userInfo.getAvatarUrl())) {
			userInfo.setAvatarUrl(aliUser.getAvatarUrl());
		}

		if (StrUtil.isBlank(userInfo.getNickName())) {
			userInfo.setNickName(aliUser.getNickName());
		}
		userInfo.setPhone(phone);
		userInfoService.saveOrUpdateUser(userInfo);

		aliUser.setMallUserId(userInfo.getId());
		aliUser.setPhone(phone);

		feignAliUserService.saveOrUpdate(aliUser, SecurityConstants.SOURCE_IN);
		// 更新redis中的token信息
		hxTokenInfo.setMallUserId(userInfo.getId());
		redisTemplate.opsForValue()
			.set(key, JSONUtil.toJsonStr(hxTokenInfo), CacheConstants.TOKEN_TIME, TimeUnit.HOURS);
		userInfo.setHxToken(StrUtil.removeAll(key, CacheConstants.MALL_USER_TOKEN));
		return userInfo;
	}

	@Override
	public void updateUser(UserInfo userInfo) {
		userInfoService.updateById(userInfo);
	}

	@Override
	public void distributionBindUser(UserInfo userInfo) {
		distributionUserService.bindUser(userInfo);
	}

}
